# cython: language_level=3
import sys
import os

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import platform
import model_phl.util_log as utils
import pandas as pd
import numpy as np
import pickle


def load_data_from_pickle(file_path_name):
    """
    加载pkl格式数据
    :param file_path_name:
    :return:
    """
    current_path = os.path.dirname(__file__)
    file_path_name = file_path_name.replace("./", current_path + "/")
    file_path_name = file_path_name.replace("\\\\", "/")
    with open(file_path_name, "rb") as infile:
        result = pickle.load(infile)
    return result


def p2score(p, pdo=40, base_score=700):
    """
    概率转换为分数的函数
    说明：概率p=坏的概率
    :param p:
    :param pdo:
    :param base_score:
    :return:
    """
    b = pdo / np.log(2)
    a = base_score + b * np.log(1 / 20)
    if p < 0:
        return -99999
    min_p = 1e-9
    max_p = 1 - min_p
    if p >= max_p:
        p = max_p
    elif p <= min_p:
        p = min_p
    score = int(a + b * np.log((1 - p) / (p)))
    if score < 300:
        return 300
    elif score > 900:
        return 900
    else:
        return score


def prob_to_score(prob, base_point=600, PDO=20):
    y = np.log(prob / (1 - prob))
    return base_point + PDO / np.log(2) * (-y)


def get_score(data_df, model_path, model_features_path):
    """
    基于模型结果和入模变量结果计算评分
    :param data_df:
    :param model_path:
    :param model_features_path:
    :return:
    """
    # 加载的模型对象
    online_model = load_data_from_pickle(model_path)
    # 特征列的列表 (判断是否为list, 如果是直接作为特征键使用, 如果不是则为pkl文件, 解析成list后使用)
    if isinstance(model_features_path, list):
        feature_cols = model_features_path
    else:
        feature_cols = load_data_from_pickle(model_features_path)
    # 模型输出概率
    proba = pd.Series(
        online_model.predict_proba(data_df[feature_cols])[:, 1], index=data_df.index
    )
    # proba = online_model.predict_proba(data_df[feature_cols])[:,1]
    # 转化打分
    model_score = proba.apply(prob_to_score)
    # model_score = proba.apply(lambda x : prob_to_score(x))
    
    return model_score


def get_user_model_score_main(features):
    """
    计算评分的主函数
    :param features:
    :return:
    """
    try:
        data_df = pd.DataFrame([features])
        # data_df.fillna(-9999, inplace=True)
        # 将None值替换为缺失值标识符
        # data_df = data_df.fillna(pd.NA)
        data_df = data_df.fillna(np.nan)

        # 新客V1版本
        creditScoreV1 = -9999

        # V1版本
        new_model_path_v1 = "./model/xgb_model_01_16.pkl"
        new_model_features_path_v1 = [
            "Ins_cnt_ty6",
            "Ins_cnt_ty5_all_rat",
            "Ins_cnt_ty6_all_rat",
            "Ins_1ty_90d_cnt_all_rat",
            "Ins_4ty_30d_cnt_all_rat",
            "Ins_4ty_90d_cnt_all_rat",
            "Ins_6ty_90d_cnt_all_rat",
            "Ins_5ty_1d_cnt_by_Ins_5ty_45d_cnt",
            "Ins_5ty_1d_cnt_by_Ins_5ty_60d_cnt",
            "Ins_5ty_1d_cnt_by_Ins_5ty_90d_cnt",
            "Ins_5ty_3d_cnt_by_Ins_5ty_30d_cnt",
            "Ins_5ty_3d_cnt_by_Ins_5ty_90d_cnt",
            "Ins_5ty_14d_cnt_by_Ins_5ty_30d_cnt",
            "Ins_5ty_14d_cnt_by_Ins_5ty_45d_cnt",
            "Ins_5ty_30d_cnt_by_Ins_5ty_90d_cnt",
            "Ins_88ty_7d_cnt_by_Ins_88ty_60d_cnt",
            "Upd_cnt_ty5_all_rat",
            "Upd_1ty_45d_cnt_all_rat",
            "Upd_1ty_60d_cnt_all_rat",
            "Upd_5ty_45d_cnt_all_rat",
            "Upd_9ty_45d_cnt_all_rat",
            "Upd_9ty_60d_cnt_by_Upd_9ty_90d_cnt",
            "sms_LoanFuzzyApp_cnt_1d_by_all_cnt_rat",
            "sms_LoanFuzzyApp_cnt_45d_by_all_cnt_rat",
            "Education",
        ]
        creditScoreV1 = get_score(
            data_df, new_model_path_v1, new_model_features_path_v1
        )[0]

        return {
            "creditScoreV1": creditScoreV1,
        }
    except Exception as e:
        utils.get_logger().error(e)
        utils.get_logger().error(features)
        return {
            "creditScoreV1": 0,
            # "oldCreditScoreV1": 0,
            # "creditScoreV2": 0,
            # "creditScoreV3": 0,
        }


if __name__ == "__main__":
    # 新客V2版本测试
    features = {
        "Ins_5ty_1d_cnt_by_Ins_5ty_90d_cnt": 0,
        "Ins_5ty_1d_cnt_by_Ins_5ty_60d_cnt": 0,
        "Ins_5ty_3d_cnt_by_Ins_5ty_90d_cnt": 0,
        "Upd_cnt_ty5_all_rat": 0,
        "Ins_5ty_3d_cnt_by_Ins_5ty_30d_cnt": 0,
        "sms_LoanFuzzyApp_cnt_45d_by_all_cnt_rat": 0,
        "Ins_5ty_1d_cnt_by_Ins_5ty_45d_cnt": 0,
        "Upd_1ty_45d_cnt_all_rat": 0.005305039787798408,
        "Ins_5ty_14d_cnt_by_Ins_5ty_30d_cnt": 0,
        "Upd_9ty_60d_cnt_by_Upd_9ty_90d_cnt": 1,
        "Upd_1ty_60d_cnt_all_rat": 0.005305039787798408,
        "Ins_5ty_14d_cnt_by_Ins_5ty_45d_cnt": 0,
        "Education": 1,
        "Ins_1ty_90d_cnt_all_rat": 0,
        "Ins_cnt_ty6": 29,
        "sms_LoanFuzzyApp_cnt_1d_by_all_cnt_rat": 0,
        "Ins_5ty_30d_cnt_by_Ins_5ty_90d_cnt": 0,
        "Upd_9ty_45d_cnt_all_rat": 0.002652519893899204,
        "Ins_cnt_ty6_all_rat": 0.07692307692307693,
        "Ins_cnt_ty5_all_rat": 0,
        "Ins_6ty_90d_cnt_all_rat": 0.002652519893899204,
        "Ins_88ty_7d_cnt_by_Ins_88ty_60d_cnt": 0,
        "Ins_4ty_30d_cnt_all_rat": 0,
        "Upd_5ty_45d_cnt_all_rat": 0,
        "Ins_4ty_90d_cnt_all_rat": 0.005305039787798408,
    }
    
    features = {
        "Ins_cnt_ty6":65.0,
        "Ins_cnt_ty5_all_rat":0.009708737864077669,
        "Ins_cnt_ty6_all_rat":0.3155339805825243,
        "Ins_1ty_90d_cnt_all_rat":None,
        "Ins_4ty_30d_cnt_all_rat":None,
        "Ins_4ty_90d_cnt_all_rat":None,
        "Ins_6ty_90d_cnt_all_rat":None,
        "Ins_5ty_1d_cnt_by_Ins_5ty_45d_cnt":1.0,
        "Ins_5ty_1d_cnt_by_Ins_5ty_60d_cnt":1.0,
        "Ins_5ty_1d_cnt_by_Ins_5ty_90d_cnt":1.0,
        "Ins_5ty_3d_cnt_by_Ins_5ty_30d_cnt":1.0,
        "Ins_5ty_3d_cnt_by_Ins_5ty_90d_cnt":1.0,
        "Ins_5ty_14d_cnt_by_Ins_5ty_30d_cnt":1.0,
        "Ins_5ty_14d_cnt_by_Ins_5ty_45d_cnt":1.0,
        "Ins_5ty_30d_cnt_by_Ins_5ty_90d_cnt":1.0,
        "Ins_88ty_7d_cnt_by_Ins_88ty_60d_cnt":1.0,
        "Upd_cnt_ty5_all_rat":None,
        "Upd_1ty_45d_cnt_all_rat":0.009708737864077669,
        "Upd_1ty_60d_cnt_all_rat":0.009708737864077669,
        "Upd_5ty_45d_cnt_all_rat":None,
        "Upd_9ty_45d_cnt_all_rat":0.02427184466019417,
        "Upd_9ty_60d_cnt_by_Upd_9ty_90d_cnt":1.0,
        "sms_LoanFuzzyApp_cnt_1d_by_all_cnt_rat":0.0318021201413428,
        "sms_LoanFuzzyApp_cnt_45d_by_all_cnt_rat":0.512367491166078,
        "Education":1,
    }
    
    features = {
        'ApplyNO': '1670471231411816',
        'Ins_cnt_ty6': 19.0,
        'Ins_cnt_ty5_all_rat': 0.04333333333333333,
        'Ins_cnt_ty6_all_rat': 0.06333333333333334,
        'Ins_1ty_90d_cnt_all_rat': np.nan,
        'Ins_4ty_30d_cnt_all_rat': np.nan,
        'Ins_4ty_90d_cnt_all_rat': np.nan,
        'Ins_6ty_90d_cnt_all_rat': np.nan,
        'Ins_5ty_1d_cnt_by_Ins_5ty_45d_cnt': 0.09090909090909091,
        'Ins_5ty_1d_cnt_by_Ins_5ty_60d_cnt': 0.09090909090909091,
        'Ins_5ty_1d_cnt_by_Ins_5ty_90d_cnt': 0.08333333333333333,
        'Ins_5ty_3d_cnt_by_Ins_5ty_30d_cnt': 0.5454545454545454,
        'Ins_5ty_3d_cnt_by_Ins_5ty_90d_cnt': 0.5,
        'Ins_5ty_14d_cnt_by_Ins_5ty_30d_cnt': 0.9090909090909091,
        'Ins_5ty_14d_cnt_by_Ins_5ty_45d_cnt': 0.9090909090909091,
        'Ins_5ty_30d_cnt_by_Ins_5ty_90d_cnt': 0.9166666666666666,
        'Ins_88ty_7d_cnt_by_Ins_88ty_60d_cnt': 0.9090909090909091,
        'Upd_cnt_ty5_all_rat': 0.006666666666666667,
        'Upd_1ty_45d_cnt_all_rat': 0.02333333333333333,
        'Upd_1ty_60d_cnt_all_rat': 0.02333333333333333,
        'Upd_5ty_45d_cnt_all_rat': 0.006666666666666667,
        'Upd_9ty_45d_cnt_all_rat': 0.003333333333333334,
        'Upd_9ty_60d_cnt_by_Upd_9ty_90d_cnt': 1.0,
        'sms_LoanFuzzyApp_cnt_1d_by_all_cnt_rat': np.nan,
        'sms_LoanFuzzyApp_cnt_45d_by_all_cnt_rat': np.nan,
        'Education': 3,
        'score2': 573
    }
    
    print(get_user_model_score_main(features))
